package com.example.util;

import com.google.common.io.BaseEncoding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AesUtil {

    private static final Logger logger = LoggerFactory.getLogger(AesUtil.class);
    private static final int IV_LENGTH = 16;

    public static String encrypt(String base64Key, String base64InitVector, String value) {
        try {
            byte[] key = Base64.getDecoder().decode(base64Key);
            byte[] initVector = Base64.getDecoder().decode(base64InitVector);

            if (initVector.length != IV_LENGTH) {
                throw new IllegalArgumentException("Invalid IV length: must be 16 bytes long");
            }

            IvParameterSpec iv = new IvParameterSpec(initVector);
            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
            return BaseEncoding.base64().encode(encrypted);
        } catch (Exception ex) {
            logger.error("Error while encrypting: ", ex);
        }
        return null;
    }

    public static String decrypt(String base64Key, String base64InitVector, String encrypted) {
        try {
            byte[] key = Base64.getDecoder().decode(base64Key);
            byte[] initVector = Base64.getDecoder().decode(base64InitVector);

            if (initVector.length != IV_LENGTH) {
                throw new IllegalArgumentException("Invalid IV length: must be 16 bytes long");
            }

            IvParameterSpec iv = new IvParameterSpec(initVector);
            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            byte[] original = cipher.doFinal(BaseEncoding.base64().decode(encrypted));
            return new String(original, StandardCharsets.UTF_8);
        } catch (Exception ex) {
            logger.error("Error while decrypting: ", ex);
        }
        return null;
    }

    public static boolean isBase64(String value) {
        try {
            BaseEncoding.base64().decode(value);
            return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}
